home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
listings
/
v_09_01
/
9n01059a
< prev
next >
Wrap
Text File
|
1990-11-14
|
3KB
|
96 lines
/* ************************* */
/* Multi-threading functions */
#include <setjmp.h>
#define TSTACKSIZE 200 /* Stack space reseved in each thread in words */
#define MAXTHREAD 20 /* Max No of concurrent threads */
#define SPINDX 1 /* Index of stack pointer into env */
#define NULL 0
static struct threaddat {
int *env ; /* Environment pointer */
int (*tfp)() ; /* Thread function pointer */
int state ; /* 0 Waiting 1 running -1 terminated */
} threaddata[MAXTHREAD] ;
/* Globals for thread() */
static jmp_buf envroot ; /* root environment */
static int threadnum = -1 ; /* Number of threads */
static int threadindx ; /* Thread indexer */
/* Takes a NULL terminated list of function pointers, sets up
the global parameters above and the root environment and then
calls threadrun() to define and run the function threads. */
thread(fplist)
int (*fplist)() ;
{
int (**fplptr)() ;
void threadrun() ;
if (threadnum == -1)
{ fplptr = &fplist ;
threadnum = 0 ;
while (*fplptr != NULL)
threaddata[threadnum++].tfp = *fplptr++ ;
threadindx = 0 ;
if (!setjmp(envroot))
threadrun() ; /* define thread environments recursivly */
/* then run them to extinction */
}
}
/* recusivly defines thread environments then runs in round robin */
void threadrun()
{
jmp_buf envthread ;
int stackspace[TSTACKSIZE] ;
if (threadindx < threadnum)
{ if (setjmp(envthread))
{ /* Will arrive here by longjmp for function dispatch */
(*threaddata[threadindx].tfp)() ; /* Start thread */
threaddata[threadindx].state = -1 ; /* terminated */
threadswitch() ;
printf("Multi-threading error - terminating ) ;
exit(1) ;
}
else
{
/* Global pointer to thread env */
threaddata[threadindx].env = envthread ;
/* Thread state to waiting to run */
threaddata[threadindx].state = 0 ;
/* Modify env value for stack with a little margin for luck */
envthread[SPINDX] = (int) &stackspace[TSTACKSIZE-5] ;
threadrun(++threadindx) ; /* Recusive call for next thread env */
}
}
else /* Run threads in round robin */
{
/* Start the ball rolling with thread 1*/
threadindx = 0 ;
longjmp(threaddata[threadindx].env, -1) ;
}
}
/* Thread switcher : Will switch to next available function thread in list.
If function threads have all terminated will terminate the threads
environment and return to the root enviroment */
threadswitch()
{ int i ;
if (threadnum != -1)
{
if (threaddata[threadindx].state != -1)
threaddata[threadindx].state = 0 ;
if (!setjmp(threaddata[threadindx].env))
{
for (i=1; i <= threadnum; i++)
{ if (++threadindx >= threadnum)
threadindx = 0 ;
if (!threaddata[threadindx].state)
{ threaddata[threadindx].state = 1 ;
longjmp(threaddata[threadindx].env, -1) ;
}
}
threadnum = -1 ;
longjmp(envroot, -1) ;
}
}
}